﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Threading;

namespace EPiServer.CdnSupport.Test
{
    /// <summary>
    /// Summary description for
    /// </summary>
    [TestClass]
    public class TestMicroCache
    {
        [TestMethod]
        public void Verify_Add_Remove_Get_Works()
        {
            bool isBusy;
            Uri val = new Uri("http://cdn.local");
            MicroCache<Uri> test = new MicroCache<Uri>(false);
            test.Add("test1", val);
            Uri retVal = test.Get("test1", out isBusy);
            Assert.IsFalse(isBusy);
            Assert.AreEqual(val, retVal);
            Assert.IsTrue(test.Remove("test1"));
            retVal = test.Get("test1", out isBusy);
            Assert.IsNull(retVal);
            Assert.IsFalse(test.Remove("test1"));
        }

        [TestMethod]
        public void Verify_Max_Items_Is_Handled()
        {
            bool isBusy;
            int retVal;
            MicroCache<int> test = new MicroCache<int>(false);

            for (int i = 0; i < MicroCache<int>.DefaultMaxCount; i++)
            {
                test.Add("test" + i.ToString(), i);
                
                retVal = test.Get("test" + i.ToString(), out isBusy);
                Assert.IsFalse(isBusy);
            }

            Assert.IsFalse(test.Add("NextKey", 44));

            retVal = test.Get("NextKey", out isBusy);
            Assert.IsTrue(isBusy);
            Assert.AreEqual(0,retVal);
            retVal = test.Get("test1", out isBusy);
            Assert.IsFalse(isBusy);
            Assert.AreEqual(1, retVal);
        }

        [TestMethod]
        public void Verify_Cleanup_Is_Working_Correctly()
        {
            bool isBusy;
            int retVal;
            MicroCache<int> test = new MicroCache<int>(false);

            int i = 0;

            for (i = 0; i < Convert.ToInt32(0.75 * MicroCache<int>.DefaultMaxCount); i++)
            {
                test.Add("test" + i.ToString(), i);

                retVal = test.Get("test" + i.ToString(), out isBusy);
                Assert.IsFalse(isBusy);
            }

            Assert.AreEqual(Convert.ToInt32(0.75 * MicroCache<int>.DefaultMaxCount), test.Count);
            test.CleanUp();
            Assert.AreEqual(Convert.ToInt32(0.75 * MicroCache<int>.DefaultMaxCount), test.Count);

            for (; i < MicroCache<int>.DefaultMaxCount; i++)
            {
                test.Add("test" + i.ToString(), i);

                retVal = test.Get("test" + i.ToString(), out isBusy);
                Assert.IsFalse(isBusy);
            }

            Assert.AreEqual(MicroCache<int>.DefaultMaxCount, test.Count);
            test.CleanUp();
            Assert.AreEqual(Convert.ToInt32(0.75 * MicroCache<int>.DefaultMaxCount), test.Count);
        }

        [TestMethod]
        public void Cleanup_Callback_Timer_Should_Execute()
        {
            using (MicroCache<int> test = new MicroCache<int>(true, TimeSpan.FromMilliseconds(1), TimeSpan.FromMilliseconds(10), 10, 0.75))
            {
                int i = 0;

                for (i = 0; i < 10; i++)
                {
                    test.Add("test" + i.ToString(), i);
                }

                Assert.AreEqual(10, test.Count);
                Thread.Sleep(TimeSpan.FromMilliseconds(50));
                Assert.AreEqual(0, test.Count);
            }
        }

        [TestMethod]
        public void Timout_Should_Trigger_Cleanup()
        {
            MicroCache<int> test = new MicroCache<int>(false,TimeSpan.FromMilliseconds(10),TimeSpan.FromMilliseconds(10),10,0.75);
            test.Add("test", 1);
            Assert.AreEqual(1, test.Count);
            System.Threading.Thread.Sleep(TimeSpan.FromMilliseconds(11));
            test.CleanUp();
            Assert.AreEqual(0, test.Count);
        }
    }
}
